package ru.nsu.ccfit.kalah.game;

import android.os.AsyncTask;
import android.util.Log;

import java.util.Map;


public class AiPlayer extends Player {

    KalahController kalahController;

    public AiPlayer(int depth) {
        this.depth = depth;
    }

    int depth ;

    @Override
    public void requestMove() {

        // TODO add async task

        kalahController = new KalahController(gameController.kalahController);

        Log.e("xxx", "AI start generate move");
        long t = System.currentTimeMillis();
        int pos = genmove();
        t = System.currentTimeMillis() - t;

        Log.e("xxx", "AI stop generate move [" + t + "] ms");
        Log.e("xxx", "AI generated move = " + pos);

        gameController.makeMove(pos);
    }


    int genmove() {

        int pos = 0;
        int value = -10000;
        int alpha = -100;


        for (int i = 1; i <= 6; ++i) {

            if (!kalahController.allow(i)) {
                continue;

            }

            kalahController.move(i);

            int temp = AlphaBetaSearch(depth, alpha, 100);
            Log.e("xxx", "pos = " + i + " mark = " + temp);
            if (temp > value) {
                pos = i;
                value = temp;
                alpha = value - 1;
            }
            kalahController.undoMove();

        }

        return pos;

    }

    int AlphaBetaSearch(int depth, int alpha, int beta) {
        if (kalahController.currentPlayer == PlayerType.SOUTH) return MinPlayer(depth, alpha, beta);
        else return MaxPlayer(depth, alpha, beta);
    }

    int MaxPlayer(int depth, int alpha, int beta) {

        if (depth == 0 || kalahController.terminal()) {
            return kalahController.mark();
        }
        int temp;
        for (int i = 6; i >= 1; --i) {
            if (!kalahController.allow(i)) {
                continue;

            }

            kalahController.move(i);

            if (!(kalahController.currentPlayer == PlayerType.SOUTH)) {
                temp = MaxPlayer(depth - 1, alpha, beta);
            } else {
                temp = MinPlayer(depth - 1, alpha, beta);
            }

            kalahController.undoMove();
            if (temp >= beta) {
                return beta;
            }

            alpha = Math.max(temp, alpha);
        }

        return alpha;


    }

    int MinPlayer(int depth, int alpha, int beta) {

        if (depth == 0 || kalahController.terminal()) {
            return kalahController.mark();
        }


        int temp;
        for (int i = 6; i >= 1; --i) {
            if (!kalahController.allow(i)) {
                continue;

            }

            kalahController.move(i);


            if (kalahController.currentPlayer == PlayerType.SOUTH) {
                temp = MinPlayer(depth - 1, alpha, beta);
            } else {
                temp = MaxPlayer(depth - 1, alpha, beta);
            }


            kalahController.undoMove();

            if (temp <= alpha) {
                return alpha;
            }

            beta = Math.min(temp, beta);
        }

        return beta;

    }
}
